package cc.catface.api.output;

import cc.catface.api.task.ShowTask;
import cc.catface.common.aspect.NetLog;
import cc.catface.common.output.BizException;
import cc.catface.common.output.Result;
import cc.catface.dao.biz.biz1.dto.PostStrBodyIPDTO;
import cn.hutool.core.io.FileUtil;
import cn.hutool.cron.CronUtil;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Cleanup;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 异常返回示例
 */
@Slf4j
@ApiSupport(order = 10)
@Api(tags = "示例模块")
@RestController
@RequestMapping("test")
@SuppressWarnings("all")
public class TestController {
    @ApiOperationSupport(order = 1)
    @NetLog("body字符串入参")
    @ApiOperation("body字符串入参")
    @PostMapping("postStrBody")//客户端body发送text类型
    public Result<List<String>> postStrBody(@RequestBody PostStrBodyIPDTO in) {
        List<String> names = new ArrayList<>();
        return Result.success(names);
    }

    /*控制定时任务*/
    @Autowired
    private ShowTask showTask;

    @ApiOperation(("启动定时任务ShowTask.*()"))
    @GetMapping("startPing")
    public Result startPing() {
        showTask.dynamicPing();
        CronUtil.start();
        return Result.success();
    }

    @ApiOperation(("停止所有定时任务ShowTask.*()"))
    @GetMapping("stopPing")
    public Result stopPing() {
        CronUtil.stop();
        return Result.success();
    }

    @ApiOperation(("移除动态定时任务ShowTask.dynamicPing()"))
    @GetMapping("removePing")
    public Result removePing() {
        showTask.removeDynamicPing();
        return Result.success();
    }

    /*文件上传和下载*/
    private static final String DIR = String.format("D:%sprojects%sidea%sspringboot-parent", File.separator, File.separator, File.separator);

    @ApiOperation("示例文件上传")
    @GetMapping("uploadFile")
    @SneakyThrows
    public Result uploadFile(@RequestPart("files") MultipartFile[] files) {
        int size = files.length;
        if (size == 0) return Result.error("未上传文件");
        for (int i = 0; i < size; i++) {
            String originalFilename = files[i].getOriginalFilename();
            log.info("uploadFile(), 接收文件{}/{}名称:{}", i + 1, size, originalFilename);
            files[i].transferTo(new File(DIR + File.separator + new SimpleDateFormat("mm-ss-").format(new Date()) + originalFilename));
        }
        return Result.success();
    }


    @ApiOperation("示例文件下载")
    @GetMapping("downloadFile")
    @SneakyThrows
    public Result downloadFile(HttpServletResponse response) {
        String filepath = DIR + File.separator + "README.md";
        log.info("downloadFile(), filepath:{}", filepath);
        File file = new File(filepath);
        if (StringUtils.isEmpty(filepath) || file == null || !file.exists()) {
            return Result.error("将要下载的文件不存在");
        }
        response.reset();
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("utf-8");//支持文件名包含中文
        response.setContentLength((int) file.length());
        response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(file.getName(), "UTF-8"));
        @Cleanup ServletOutputStream os = response.getOutputStream();
        os.write(FileUtil.readBytes(file));
        return Result.success();
    }

    /*服务器时间*/
    @ApiOperation(value = "服务器时间")
    @GetMapping("time")
    @SneakyThrows
    public Result<String> time() {
        Thread.sleep(2000);
        return Result.success(new Date().toLocaleString());
    }

    /*异常示例*/
    @ApiOperation(value = "空异常")
    @GetMapping("null")
    public void nullE() {
        Object o = null;
        log.info(o.toString());
    }

    @ApiOperation(value = "请求方法错误")
    @PostMapping("methodE")
    public void methodE() {

    }

    @ApiOperation(value = "请求参数错误")
    @PostMapping("paramE")
    public Result paramE(@RequestBody Result body) {
        return Result.success(body);
    }

    @ApiOperation(value = "通用Exception错误")
    @GetMapping("err")
    public void err() {
        Integer.parseInt("abc");
    }

    @ApiOperation(value = "自定义业务异常")
    @GetMapping("biz")
    public void bizE() {
        //throw new BizException();
        //throw new BizException(ErrorCode.ERROR_INTERNAL);
        //throw new BizException(ErrorCode.ERROR_INTERNAL, new RuntimeException("runtime exception!"));
        //throw new BizException("runtime exception!");
        //throw new BizException("-0x99","runtime exception!");
        throw new BizException("-0x99", "runtime exception!", new RuntimeException("runtime exception!"));
    }
}
